/*
** Copyright (c) 2001 PIXAR.  All rights reserved.  This program or
** documentation contains proprietary confidential information and trade
** secrets of PIXAR.  Reverse engineering of object code is prohibited.
** Use of copyright notice is precautionary and does not imply
** publication.
**
**                      RESTRICTED RIGHTS NOTICE
**
** Use, duplication, or disclosure by the Government is subject to the
** following restrictions:  For civilian agencies, subparagraphs (a) through
** (d) of the Commercial Computer Software--Restricted Rights clause at
** 52.227-19 of the FAR; and, for units of the Department of Defense, DoD
** Supplement to the FAR, clause 52.227-7013 (c)(1)(ii), Rights in
** Technical Data and Computer Software.
**
** Pixar
** 1200 Park Ave
** Emeryville, CA 94608
**
** ----------------------------------------------------------------------------
*/
/* code generated by slim 6.0, RAT 6.0 (Mar 11 2004 04:21:00) */
/* for kidd@localhost at: Sat Mar 26 16:31:53 FLE Standard Time 2005 */

/* includes ---------------------------------*/
#include "pxslRayUtil.h"

/* defines ----------------------------------*/
#define SLIM_TYPEID_surface 0
#define SLIM_TYPEID_displacement 1
#define SLIM_TYPEID_volume 2
#define SLIM_TYPEID_light 3
#define SLIM_VERSION 600
#define SLIM_SHADERTYPE surface
#define SLIM_SHADERTYPEID SLIM_TYPEID_surface
#define SLIM_INSTANCETYPE shadingmodel
#define SLIM_INSTANCENAME Velvet

/* shader body ------------------------------*/
SLIM_SHADERTYPE
SLIM_INSTANCENAME (
)
{

/* static functions ----------------------*/

	    void pxslMayaUV (
		point STMatrix0;
		point STMatrix1;
		output point Q; 
		output vector dQu;
		output vector dQv;
	    ) 
	    {
		extern float s, t, du, dv;
	    	setzcomp(Q, 0);
		if ( STMatrix0 == point(1,0,0) &&
		     STMatrix1 == point(0,1,0) )
		{
		    /* no connection has been made, convert from
		    	std Maya to std RenderMan parameterization
			for nurbs. */
		    setxcomp(Q, t);
		    setycomp(Q, 1-s);
		}
		else
		{
		    setxcomp(Q, vector(s, t, 1) . 
		    	    	vector(transform("shader", STMatrix0)) );
		    setycomp(Q, vector(s, t, 1) . 
		    	    	vector(transform("shader", STMatrix1)) );
		}
		dQu = vector Du(Q)*du;
		dQv = vector Dv(Q)*dv;
	    }
	

	/*
	 * velvet.sl -- velvet
	 *
	 * DESCRIPTION:
	 *   An attempt at a velvet surface.
	 *   This phenomenological model contains three compnents:
	 *   - A retroreflective lobe (back toward the light source)
	 *   - Scattering near the horizon, regardless of incident direction
	 *   - A diffuse color
	 * 
	 * PARAMETERS:
	 *   Ks:        controls retroreflective lobe
	 *   Kd:        scales diffuse color
	 *   Ka:        ambient component (affects diffuse color only)
	 *   sheen:     color of retroreflective lobe and horizon scattering
	 *   roughness: shininess of fabric (controls retroreflection only)
         *   edginess:  controls the amount of horizon scattering
	 *   Cs:        diffuse color
	 *
	 * ANTIALIASING: should antialias itself fairly well
	 *
	 * AUTHOR: written by Stephen H. Westin, Ford Motor Company
	 *
	 * HISTORY:
	 *
	 * last modified  28 January 1997 S. H. Westin
	 * modified for slim:
	 *  	support for __nonspecular
	 *  	conversion to function
	 */
	void
	pxslVelvet (color SurfaceColor;
	    	    color SurfaceOpacity;
        	    color sheen;
	    	    float Ka;
        	    float Kd;
        	    float Ks;
        	    float roughness;
		    float edginess;
		    output color CI;
		    output color OI;
	  )
	{
	  extern vector I;
	  extern normal N;
	  extern point P;
	  normal Ns = pxslUtilShadingNormal(N);
	  vector V;                      /* Normalized eye vector */
	  vector H;                      /* Bisector vector for Phong/Blinn */
	  vector Ln;                     /* Normalized vector to light */
	  color shiny;                   /* Non-diffuse components */
	  float cosine, sine;            /* Components for horizon scatter */
	  V = -normalize (I);
	  shiny = 0;
	  illuminance ( P, Ns, 1.57079632679489661923 /* Hemisphere */ ) {
	    extern color Cl;
	    extern vector L;
	    float nonspec = 0;
	    lightsource ("__nonspecular", nonspec);
	    if (nonspec < 1) {
	    	Cl *= (1 - nonspec);
		Ln = normalize ( L );
		/* Retroreflective lobe */
		cosine = max ( Ln.V, 0 );
		shiny += pow ( cosine, 1.0/roughness ) * Ks * Cl * sheen;
		/* Horizon scattering */
		cosine = max ( Ns.V, 0 );
		sine = sqrt (1.0-cosine*cosine);
		shiny += pow ( sine, edginess ) * Ln.Ns * Cl * sheen;
	    }
	  }
	  OI = SurfaceOpacity;
	  CI = SurfaceOpacity * SurfaceColor * (Ka*ambient() + Kd*diffuse(Ns))
		 + shiny;

	}
      

#include "pxslUtil.h"
    	void
	pxslCNoise( float frequency;
	    	    point p;
		    vector dpu;
		    vector dpv;
		    output color result;
		   )
	{
	    point pp = frequency * p;
	    vector dppu = frequency * dpu;
	    vector dppv = frequency * dpv;
	    result = pxslFilteredCNoise(pp, dppu, dppv);
	}
    

/* dynamic functions ------------------------*/

/* local variables --------------------------*/
  point tmp0;
  color tmp3;
  color tmp4;
  color tmp5;
  vector tmp1;
  vector tmp2;

/* main body --------------------------------*/
  pxslMayaUV ( /* MayaUV_0 */
    point(1,0,0), /* STMatrix0 */
    point(0,1,0), /* STMatrix1 */
    tmp0, /* Q */ 
    tmp1, /* dQu */ 
    tmp2  /* dQv */ 
    );
  pxslCNoise ( /* Noise_0 */
    10.9, /* frequency */
    tmp0, /* p */ 
    tmp1, /* dpu */ 
    tmp2, /* dpv */ 
    tmp3  /* result */ 
    );
  pxslVelvet ( /* Velvet */
    tmp3, /* Velvet Color */ 
    color(1,1,1), /* Opacity */
    color(.25,.25,.25), /* Velvet Sheen */
    .05, /* Ka */
    1.00, /* Kd */
    .1, /* Ks */
    .05, /* Roughness */
    10, /* Edginess */
    tmp4, /* CI */ 
    tmp5  /* OI */ 
    );
  Ci = tmp4;
  Oi = tmp5;
}

